package com.sds.sweng.swat.miplatform.service.figures.components;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Element;
import org.dom4j.Node;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.FreeformLayeredPane;
import org.eclipse.draw2d.FreeformViewport;
import org.eclipse.draw2d.GridData;
import org.eclipse.draw2d.GridLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.ScrollPane;
import org.eclipse.draw2d.geometry.Point;

import com.sds.sweng.swat.miplatform.service.graphics.ComponentDrawer;
import com.sds.sweng.swat.miplatform.service.graphics.ComponentUtils;

public class GridComponent extends ScrollPane implements MiplatformComponent {

	protected Node component;
	protected Node parent;
	protected ComponentDrawer drawer;

	protected List<Node> columns;
	protected List<Node> head;
	protected List<Node> body;

	protected FreeformLayeredPane gridPane;
	protected GridLayout layout;

	protected static final int COLUMN_HEIGHT = 20;

	protected String bindDataset;

	public GridComponent(Node component, Node parent, ComponentDrawer drawer) {
		this.component = component;
		this.parent = parent;
		this.drawer = drawer;

		setBounds(ComponentUtils.getComponentBound(component, parent));
		setSize(getBounds().width, getBounds().height);
		setBorder(new LineBorder(ColorConstants.black));

		gridPane = new FreeformLayeredPane();

		setViewport(new FreeformViewport());
		setScrollBarVisibility(AUTOMATIC);
		setContents(gridPane);

		initComponent();
	}

	protected void initComponent() {
		bindDataset = component.valueOf("@BindDataset");

		columns = component.selectNodes("contents/format/columns/col");
		head = component.selectNodes("contents/format/head/cell");
		body = component.selectNodes("contents/format/body/cell");

		layout = new GridLayout();
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = columns.size();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		layout.horizontalSpacing = 0;
		layout.verticalSpacing = 0;

		gridPane.setLayoutManager(layout);

		drawColumns();
		drawBody();
	}

	public void setDrawer(ComponentDrawer drawer) {
		this.drawer = drawer;
	}

	public Node getNode() {
		return component;
	}

	public String getId() {
		Element parent = component.getParent();
		String id = component.valueOf("@Id");

		while (!"Form".equals(parent.getName())) {
			String parentId = parent.valueOf("@Id");

			if (!StringUtils.isEmpty(parentId)) {
				id = parentId + "." + id;
			}

			parent = parent.getParent();
		}

		return id;
	}

	protected int getColumnWidth(Node column) {
		int columnIndex = Integer.parseInt(column.valueOf("@col"));
		int colspan = 1;
		int columnWidth = 0;

		if (!StringUtils.isEmpty(column.valueOf("@colspan"))) {
			colspan = Integer.parseInt(column.valueOf("@colspan"));
		}

		for (int i=columnIndex;i<columnIndex+colspan;i++) {
			columnWidth += Integer.parseInt(columns.get(i).valueOf("@width"));
		}

		return columnWidth;
	}

	protected void drawColumns() {
		for (int i=0;i<head.size();i++) {
			Node headNode = head.get(i);
			String columnText = headNode.valueOf("@text");

			Label column = new Label(columnText);
			column.setBorder(new LineBorder(ColorConstants.black));

			int colspan = 1;
			int rowspan = 1;

			if (!StringUtils.isEmpty(headNode.valueOf("@colspan"))) {
				colspan = Integer.parseInt(headNode.valueOf("@colspan"));
			}

			if (!StringUtils.isEmpty(headNode.valueOf("@rowspan"))) {
				rowspan = Integer.parseInt(headNode.valueOf("@rowspan"));
			}

			int columnWidth = getColumnWidth(headNode);
			column.setSize(columnWidth, COLUMN_HEIGHT);

			drawColumn(column, colspan, rowspan);
		}
	}

	protected void drawBody() {
		for (int i=0;i<body.size();i++) {
			Node bodyNode = body.get(i);
			String colid = bodyNode.valueOf("@colid");

			GridBody gridBody = new GridBody(bodyNode, component, bindDataset, colid);
			gridBody.setDrawer(drawer);

			Point parentLocation = new Point(ComponentUtils.getComponentBound(component, parent).x,
					ComponentUtils.getComponentBound(component, parent).y);
			gridBody.setParentLocation(parentLocation);

			int colspan = 1;
			int rowspan = 1;

			if (!StringUtils.isEmpty(bodyNode.valueOf("@colspan"))) {
				colspan = Integer.parseInt(bodyNode.valueOf("@colspan"));
			}

			if (!StringUtils.isEmpty(bodyNode.valueOf("@rowspan"))) {
				rowspan = Integer.parseInt(bodyNode.valueOf("@rowspan"));
			}

			int columnWidth = getColumnWidth(bodyNode);
			gridBody.setSize(columnWidth, COLUMN_HEIGHT);

			drawBody(gridBody, colspan, rowspan);
		}
	}

	private int getColumnLocationX(int columnIndex) {
		int x = 0;

		for (int i=0;i<columnIndex;i++) {
			x += Integer.parseInt(columns.get(i).valueOf("@width"));
		}

		return x;
	}

	protected void drawColumn(IFigure column, int colspan, int rowspan) {
		GridData gridData = new GridData();
		gridData.widthHint = column.getSize().width;
		gridData.heightHint = column.getSize().height * rowspan;
		gridData.horizontalSpan = colspan;
		gridData.verticalSpan = rowspan;

		layout.setConstraint(column, gridData);
		gridPane.add(column);
	}

	protected void drawBody(GridBody gridBody, int colspan, int rowspan) {
		GridData gridData = new GridData();
		gridData.widthHint = gridBody.getSize().width;
		gridData.heightHint = gridBody.getSize().height * rowspan;
		gridData.horizontalSpan = colspan;
		gridData.verticalSpan = rowspan;

		layout.setConstraint(gridBody, gridData);
		gridPane.add(gridBody);

		if (gridBody.getId() != null) {
			drawer.designArea.addValidationComponent(gridBody.getId(), gridBody);
		}
	}

}
